package com.szqhyxj.youxiangju.biz.register;

import com.szqhyxj.youxiangju.biz.core.TokenManager;
import com.szqhyxj.youxiangju.biz.core.UserInfo;
import com.szqhyxj.youxiangju.biz.core.UserInfoManger;
import com.szqhyxj.youxiangju.biz.core.UserInfoModel;
import com.szqhyxj.youxiangju.biz.login.LoginModel;
import com.szqhyxj.youxiangju.sys.BaseResult;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class RegisterPresenter implements RegisterContract.Presenter {

    private static final String TAG = RegisterPresenter.class.getSimpleName();

    private RegisterContract.View view;

    private RegisterModel.RegisterEntity registerEntity;

    RegisterPresenter(RegisterContract.View view) {
        this.view = view;
        registerEntity = new RegisterModel.RegisterEntity();
    }

    @Override
    public void setAccount(String account) {
        registerEntity.setAccount(account);
        checkRegisterEnable();
    }

    @Override
    public void setVerificationCode(String verificationCode) {
        registerEntity.setVerificationCode(verificationCode);
        checkRegisterEnable();
    }

    @Override
    public void setPassword(String password) {
        registerEntity.setPassword(password);
        checkRegisterEnable();
    }

    @Override
    public void setEnsurePassword(String ensurePassword) {
        registerEntity.setEnsurePassword(ensurePassword);
        checkRegisterEnable();
    }

    @Override
    public void setReferralCode(String referralCode) {
        registerEntity.setReferralCode(referralCode);
        checkRegisterEnable();
    }


    @Override
    public void setAgree(boolean agree) {
        this.registerEntity.setAgree(agree);
        checkRegisterEnable();
    }


    private void checkRegisterEnable() {
        if (registerEntity.valid()) {
            view.showRegisterEnable();

        } else {
            view.showRegisterDisable();

        }
    }


    private ArrayList<Disposable> disposables = new ArrayList<>();

    private static final int MINUTE = 60;

    @Override
    public void acquireVerificationCode() {
        view.showLoading();
        disposables.add(RegisterModel.sms(this.registerEntity)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        new Consumer<BaseResult>() {
                            @Override
                            public void accept(BaseResult baseResult) {
                                view.dismissLoading();
                                if (baseResult.businessLogicSuccess()) {
                                    view.showAcquiredVerificationCodeSuccess();
                                    view.showAcquiringVerificationCode(MINUTE);
                                    startCountDown();
                                } else {

                                    view.showAcquiredVerificationCodeFail(baseResult.getMessage());
                                    view.showAcquiredVerificationCode();

                                }
                            }
                        },
                        new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) {
                                view.dismissLoading();
                                view.showAcquiredVerificationCodeFail(throwable.getMessage());
                            }
                        }
                )
        );
    }

    private void startCountDown() {
        disposables.add(Observable
                .interval(0, 1, TimeUnit.SECONDS)
                .take(MINUTE)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) {
                        if (aLong == MINUTE - 1) {
                            view.showAcquiredVerificationCode();
                        } else {
                            view.showAcquiringVerificationCode((int) (MINUTE - aLong - 1));
                        }
                    }
                }));
    }

    @Override
    public void register() {
        if (registerEntity.getPassword().equals(registerEntity.getEnsurePassword())) {

            view.showLoading();
            disposables.add(
                    RegisterModel
                            .register(this.registerEntity)
                            .subscribeOn(Schedulers.io())
                            .flatMap(
                                    new Function<BaseResult, ObservableSource<BaseResult<LoginModel.LoginResult>>>() {
                                        @Override
                                        public ObservableSource<BaseResult<LoginModel.LoginResult>> apply(BaseResult baseResult) {
                                            view.dismissLoading();
                                            if (baseResult.businessLogicSuccess()) {
                                                return LoginModel.login(new LoginModel.LoginEntity(
                                                        RegisterPresenter.this.registerEntity.getPassword(),
                                                        RegisterPresenter.this.registerEntity.getAccount()
                                                ));
                                            } else {
                                                return Observable.error(new Exception(baseResult.getMessage()));
                                            }
                                        }
                                    }
                            )
                            .flatMap(
                                    new Function<BaseResult<LoginModel.LoginResult>, ObservableSource<BaseResult<UserInfo>>>() {
                                        @Override
                                        public ObservableSource<BaseResult<UserInfo>> apply(BaseResult<LoginModel.LoginResult> loginResult) {
                                            view.dismissLoading();
                                            if (loginResult.businessLogicSuccess()) {
                                                TokenManager.INSTANCE.setToken(loginResult.getData().getToken());
                                                return UserInfoModel.loadUserInfo();
                                            } else {
                                                return Observable.error(new Exception(loginResult.getMessage()));
                                            }
                                        }
                                    }
                            )
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(
                                    new Consumer<BaseResult<UserInfo>>() {
                                        @Override
                                        public void accept(BaseResult<UserInfo> userInfoResult) {
                                            view.dismissLoading();
                                            if (userInfoResult.businessLogicSuccess()) {
                                                UserInfoManger.INSTANCE.setUser(userInfoResult.getData());
                                                RegisterPresenter.this.view.showRegisterSuccess();
                                                view.showToast("注册成功!");
                                            } else {
                                                view.showToast(userInfoResult.getMessage());
                                                RegisterPresenter.this.view.showRegisterFail(userInfoResult.getMessage());
                                            }
                                        }
                                    },
                                    new Consumer<Throwable>() {
                                        @Override
                                        public void accept(Throwable throwable) {
                                            view.dismissLoading();
                                            view.showToast(throwable.getMessage());
                                            RegisterPresenter.this.view.showRegisterFail(throwable.getMessage());

                                        }
                                    }
                            )
            );
        } else {
            view.showToast("密码和再次输入的密码需一致！");
        }
    }

    @Override
    public void userContract() {
        view.navToUserContract();
    }

    @Override
    public void scan() {
        view.navToScan();
    }

    @Override
    public void back() {
        view.navBack();
    }

    @Override
    public void onDestroy() {
        for (Disposable disposable : disposables) {
            disposable.dispose();
        }
    }
}